/*
*  Copyright (c) 2001 Sun Microsystems, Inc.  All rights
*  reserved.
*
*  Redistribution and use in source and binary forms, with or without
*  modification, are permitted provided that the following conditions
*  are met:
*
*  1. Redistributions of source code must retain the above copyright
*  notice, this list of conditions and the following disclaimer.
*
*  2. Redistributions in binary form must reproduce the above copyright
*  notice, this list of conditions and the following disclaimer in
*  the documentation and/or other materials provided with the
*  distribution.
*
*  3. The end-user documentation included with the redistribution,
*  if any, must include the following acknowledgment:
*  "This product includes software developed by the
*  Sun Microsystems, Inc. for Project JXTA."
*  Alternately, this acknowledgment may appear in the software itself,
*  if and wherever such third-party acknowledgments normally appear.
*
*  4. The groups "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA"
*  must not be used to endorse or promote products derived from this
*  software without prior written permission. For written
*  permission, please contact Project JXTA at http://www.jxta.org.
*
*  5. Products derived from this software may not be called "JXTA",
*  nor may "JXTA" appear in their group, without prior written
*  permission of Sun.
*
*  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
*  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
*  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
*  DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
*  ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
*  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
*  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
*  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
*  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
*  SUCH DAMAGE.
*  ====================================================================
*
*  This software consists of voluntary contributions made by many
*  individuals on behalf of Project JXTA.  For more
*  information on Project JXTA, please see
*  <http://www.jxta.org/>.
*
*  This license is based on the BSD license adopted by the Apache Foundation.
*
*  $Id: SharePanel.java,v 1.10 2007/01/26 21:54:31 bondolo Exp $
*/

package net.jxta.myjxta.ui;

import net.jxta.logging.Logging;
import net.jxta.myjxta.util.Env;
import net.jxta.myjxta.util.Resources;
import net.jxta.myjxta.util.Share;
import net.jxta.myjxta.util.exec.ExecFactory;
import net.jxta.myjxta.util.objectmodel.GroupNode;
import net.jxta.myjxta.util.objectmodel.JxtaNode;
import net.jxta.myjxta.util.objectmodel.ShareNode;
import net.jxta.peergroup.PeerGroup;
import net.jxta.share.ContentAdvertisement;
import net.jxta.share.client.GetContentRequest;

import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * A panel that downloads a desired share
 *
 * @version $Id: SharePanel.java,v 1.10 2007/01/26 21:54:31 bondolo Exp $
 *
 * @author Dorothea Wiarda [wiarda at jxta dot org]
 * @author Frank Toennies [nano at jxta dot org]
 */

public final class SharePanel
    extends JPanel
    implements Dismissable {

    private static final char PERCENT = '%';
//    private static final char SPACE = ' ';
    private static final char SEMICOLON = ';';
    private static final char[] ESCAPE = { SEMICOLON };
    private static final String HEX = "\\x";
    private static final ResourceBundle STRINGS = Resources.getStrings();
    private static final Logger LOG = Logger.getLogger(SharePanel.class.getName());
        
    /** The progressbar that monitors the progress */
    private final JProgressBar progress;

    /** The GetContentRequest instance that retrieves the file */
    private GetContentRequest request = null;

    /** The location where we want to save this file */
    private File savePath;

    /** The label describing the current download */
    private final JLabel description;

    /** Should we display this  file in the browser */
    private boolean displayInBrowser = false;

    /**
     * Create a new ProgressMonitor panel
     *
     * @param savePath the path where to save the file
     * @param node the ShareNode describing the share to downloard
     */
    public SharePanel(File savePath, ShareNode node) {
        super();

        this.savePath = savePath;

        GridBagLayout gbl = new GridBagLayout();
        GridBagConstraints gbc = new GridBagConstraints();
        Share share = node.getShare();
        GroupNode group = null;

        // find the group node
        JxtaNode parent = (JxtaNode)node.getParent();
        
        while (parent != null &&
            !(parent instanceof GroupNode) ) {
            parent = (JxtaNode)parent.getParent();
        }
        if( parent != null && parent instanceof GroupNode) {
            group = (GroupNode)parent;
        }


        // set the panel ui parameters
        setLayout(gbl);
        setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
        gbc.insets = new Insets(3, 3, 3, 3);

        // add the description
        description = new JLabel(STRINGS.getString("label.share.download") +
                                 " " + share.getContentAdvertisement().getName());
        gbc.gridx = gbc.gridy = 0;
        gbc.anchor = GridBagConstraints.WEST;
        gbc.fill = GridBagConstraints.NONE;
        add(description);
        gbl.setConstraints(description, gbc);

        // add the progresbar
        progress = new JProgressBar(0,100);
        progress.setStringPainted(true);
        gbc.gridy++;
        gbc.weightx = 1;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        add(progress);
        gbl.setConstraints(progress,gbc);

        // add the stop button
        gbc.gridy++;
        gbc.weightx= 0;
        gbc.fill = GridBagConstraints.NONE;
        gbc.anchor = GridBagConstraints.CENTER;
        
//        JButton b = new JButton(STRINGS.getString("action.cancel"));
//        
//        b.addActionListener(new ActionListener() {
//                                public void actionPerformed(ActionEvent ae) {
//                                    stopProcess();
//                                }
//                            }
//                           );
//
//        add(b);
//        gbl.setConstraints(b,gbc);

        if( savePath == null) {
            try {
                displayInBrowser = true;
                String base = System.getProperty(Env.MYJXTA);
                File tmp = new File(base + File.separator + Env.TMP);
                tmp.mkdirs();

                this.savePath = File.createTempFile("Share",
                                                    share.getContentAdvertisement().getName(),
                                                    tmp);
                this.savePath.deleteOnExit();
            } catch(Exception iox) {
                description.setText(STRINGS.getString("error.share.download.invalid") +
                                    ": " + iox.getMessage());
                return;
            }

        }
        request = new ContentRequest( group.getGroup().getPeerGroup(),
                                      share.getContentAdvertisement(),
                                      this.savePath);
        
        setSize(new Dimension(UIConstants.SHARE_WIDTH,
            UIConstants.SHARE_HEIGHT));
        setPreferredSize(getSize());
        setMinimumSize(getPreferredSize());
    }

    public void dismiss() {
        stopProcess(false);
    }
    
    /**
     * Cancel the process that called this ProgressMonitor 
     */
    private void stopProcess(boolean showIfSuccessfull) {
        boolean deleteFile = false;

        if (request != null) {
            if (! request.isDone()) {
                deleteFile = true;
            }

            request.cancel();
        }

        if (deleteFile) {
            Env.delete(this.savePath);
        } else if (displayInBrowser && showIfSuccessfull) {
            String p = null;
            
            try {
                p = this.savePath.toURI().toURL().toString();
            } catch (MalformedURLException mue) {
                if (Logging.SHOW_FINE && LOG.isLoggable(Level.FINE)) {
                    LOG.log(Level.FINE, "invalid url: " + p, mue);
                }
            }
            
            if (p != null) {     
                for (int i = 0; i < ESCAPE.length; i++) {
                    String hx = Integer.toString(ESCAPE[i], 16).toUpperCase();

                    p = p.replaceAll(HEX + hx, PERCENT + hx);
                }

                try {
                    ExecFactory.getExec().execDocument(new URL(p));
                } catch (MalformedURLException mue) {
                    if (Logging.SHOW_FINE && LOG.isLoggable(Level.FINE)) {
                        LOG.log(Level.FINE, "invalid url: " + this.savePath,
                                mue);
                    }
                }
            } else if (Logging.SHOW_FINE && LOG.isLoggable(Level.FINE)) {
                LOG.fine("invalid url: " + this.savePath);
            }
        }
    }

//    /**
//     * Change the percentage displayed in the progess bar
//     *
//     * @param percent the new percentage number
//     */
//    public void updateProgress(final int percent) {
//        SwingUtilities.invokeLater(
//            new Runnable() {
//                public void run() {
//                    progress.setValue(percent);
//                }
//            }
//        );
//    }

    /**
     * Called if a download failure occured
     */
    private void reportFailure() {
        SwingUtilities.invokeLater(
            new Runnable() {
                public void run() {
                    description.setText(STRINGS.getString("error.share.download.invalid"));
                }
            }
        );
    }

    /**
      * The class that  downloads the file 
      */
    class ContentRequest extends GetContentRequest {
        /**
         * Create a new ContentRequest instance
         *
         * @param group the PeerGroup in which the share lives
         * @param source the ContentAdvertisement of the share to download
         * @param destination the file to which to save the data
         */
        public ContentRequest(PeerGroup group,
                              ContentAdvertisement source,
                              File destination) {
            super(group,source,destination);
        }

        /**
         * This method is called when the download is complete.
         */
        public void notifyDone() {
            stopProcess(true);
        }

        /**
         * This method is called if the download fails.
         */
        public void notifyFailure() {
            Env.delete(savePath);
            stopProcess(false);
            reportFailure();
        }

        /**
         * This method as called as more of the file has been downloaded.
         *
         * @param percentage the percentage of the file that has been
         *                   downloaded so far.
         */
        public void notifyUpdate(int percentage) {
            progress.setValue(percentage);
        }
    }
}
